/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package query.parser;

import java.util.ArrayList;
import java.util.List;
import org.streets.database.SQLNestedException;

/**
 *
 * @author dzb
 */
public abstract class AbstractParser {

	protected ITokenizer tokenizer;

	public AbstractParser(ITokenizer tokenizer) {
		this.tokenizer = tokenizer;
	}

	protected void expectToken(String token) {
		if (getCurrentToken().equalsIgnoreCase(token))
			throw new SQLNestedException("Expected token["+token+"] not found, current token "+getCurrentToken()+". position:"+tokenizer.getPosition());
		else
			readNextToken();
	}

	protected void exceptToken(String[] tokens) {
		for (String tk : tokens) {
			expectToken(tk);
		}
	}

	protected void readNextToken() {
		tokenizer.readNextToken();;
	}

	protected String getCurrentToken() {
		return tokenizer.getCurrent().getValue();
	}

	protected ITokenizer getTokenizer() {
		return tokenizer;
	}

	private void setTokenizer(ITokenizer tokenizer) {
		this.tokenizer = tokenizer;
	}

	protected IExpression processExpression() {
		ExpressionParser parser = new ExpressionParser(tokenizer);
		return parser.execute();
	}

    private String GetOperator() {
		if ( tokenizer.isNextToken( "=", ">=", "<=", "!=", "<>", "IN", "ANY", "LIKE" ) )
		{
			String token = tokenizer.getCurrent().getValue();
			readNextToken();
			return token;
		}
		else
			throw new SQLNestedException("Expected token["+tokenizer.getCurrent().getValue()+"] not found, current token "+getCurrentToken()+". position:"+tokenizer.getPosition());			
	}

	protected CriteriaExpression ProcessCriteriaExpression(IExpression parent )
	{
		CriteriaExpression expression = new CriteriaExpression( parent );
		expression.setLeft(processExpression());
		expression.setOperator(GetOperator());
		expression.setRight(processExpression());

		return expression;
	}

	protected String getIdentifier()
	{
		if ( ! tokenizer.hasMoreTokens())
			throw new SQLNestedException("Identifier expected");			

		String identifier = getCurrentToken();
		readNextToken();
		return identifier;
	}

	protected List<String> getIdentifierList()
	{
		List<String> identifiers = new ArrayList<String>();
		do
		{
			identifiers.add( getIdentifier() );
		}
		while ( tokenizer.tokenEquals( Constants.Comma ) );

		return identifiers;
	}

	protected String GetDotNotationIdentifier()
	{
		String token;
		token = "";

		do
		{
			token += ( token != "" ? Constants.Dot : "" ) + getIdentifier();
		}
		while ( tokenizer.tokenEquals(Constants.Dot ) );
		
		return token;
	}

	protected boolean HasTerminator()
	{
		boolean result = tokenizer.isNextToken( Constants.SemiColon );
		if ( result )
			tokenizer.readNextToken();
		return result;
	}

//	protected Top GetTop()
//	{
		// consume 'TOP' token first
//		Tokenizer.ExpectToken( Constants.Top );
//
//		Top top;
//		if ( Tokenizer.IsNextToken( Constants.OpenBracket ) )
//		{
//			using ( Tokenizer.ExpectBrackets() )
//			{
//				var parser = new ExpressionParser( Tokenizer );
//				var expression = parser.Execute();
//				if ( expression != null )
//				{
//					top = new Top( expression, true );
//					return top;
//				}
//				else
//					throw new SyntaxException( "TOP clause requires an expression" );
//			}
//		}
//		else
//		{
//			if ( Tokenizer.Current.Type != TokenType.Numeric || Tokenizer.Current.Value.Contains( "." ) )
//				throw new SyntaxException( String.Format( "Expected integer but found: '{0}'", Tokenizer.Current.Value ) );
//
//			top = new Top( new StringExpression( Tokenizer.Current.Value, null ), false );
//			ReadNextToken();
//		}
//
//		if ( Tokenizer.TokenEquals( Constants.Percent ) )
//			top.Percent = true;
//
//		return top;
//	}

}
